# Forecast generator sourcing World Weather Online. 
# Request generator at http://www.worldweatheronline.com/feed-generater.aspx (sic) 
# Usage policy:
#   We request our free local weather API users to not exceed 500 requests per
#   hour and also follow proper caching of data at their end before making the
#   request for same location within 15 min. 

import datetime 
import json 
import logging
import urllib.request

from forecasts import common

class ForecastGen(common.ForecastGen):
    shortname = 'wwonline'
    _baseurl = 'http://free.worldweatheronline.com/\
feed/weather.ashx?q={lat:f},{lon:f}&format=json&num_of_days=5&key={key}'

    def generate_url(self, latitude, longitude):
        with open('apikeys/wwonline.key') as keyfile:
            apikey = keyfile.read().strip()
        self.url = self._baseurl.format(
            key=apikey, 
            lat=float(latitude), 
            lon=float(longitude))
        self.log.debug('URL: ' + self.url)

    def fetchdata(self, url=None):
        """Fetches the data from the web. 

        Returns a format suitable for use in processdata().
        """
        if url == None:
            url = self.url
        with urllib.request.urlopen(url) as f:
            data = json.loads(f.read().decode('utf-8'))
        return data

    def processdata(self, data):
        """data: a dictionary-ish thing as generated by json.loads()

        This is the one function that heavily depends on the json input being 
        as expected.
        """
        forecasts = {}
        # Figuring out what "today" is in local time.  WWO provides a date
        # which is assumed to be local.
        todaystring = data['data']['weather'][0]['date']
        format = '%Y-%m-%d'
        today = datetime.datetime.strptime(todaystring, format).date()
        for day in data['data']['weather']:
            thatday = datetime.datetime.strptime(day['date'], format).date()
            numdays = (thatday - today).days
            forecasts[numdays] = common.Forecast(
                today, 
                thatday,
                int(day['tempMinC']),
                int(day['tempMaxC']))
        self.log.debug('Extracted {0} forecasts from the feed'.format(
            len(forecasts)))
        return forecasts

if __name__ == '__main__':
    logging.basicConfig(format='%(levelname)s-%(name)s: %(message)s', level=logging.DEBUG)
    gen = ForecastGen(-37.02, 174.80)
    print(gen.getforecast(1))
    print(gen.getforecast(2))
    print(gen.getforecast(3))
